import numpy as np


class Tensor:
    def __init__(self, data, autograd=False):
        self.data = np.array(data)

    def __str__(self):
        return "<Tensor data="+str(self.data)+" shape="+str(self.shape)+">"

    def __neg__(self):
        return Tensor(self.data * -1)

    def __add__(self, other):
        return Tensor(self.data + other.data)

    def __mul__(self, other):
        return Tensor(self.data * other.data)

    def __sub__(self, other):
        return Tensor(self.data - other.data)

    def __truediv__(self, other):
        return Tensor(self.data / other.data)

    def __getitem__(self, item):
        return self.data[item]

    def __len__(self):
        return len(self.data)

    def sum(self):
        return Tensor(np.sum(self.data))

    def dot(self, other):
        return (self * other).sum()

    def matmul(self, other):
        return Tensor(self.data @ other.data)

    def transpose(self):
        return Tensor(self.data.T)

    def reshape(self, shape):
        return Tensor(self.data.reshape(shape))

    def argmax(self):
        return self.data.argmax()

    @property
    def shape(self):
        return self.data.shape
